package me.tonywang.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.util.List;

@Configuration
public class ObjectMapperBuilderConfiguration {

    private final ApplicationContext applicationContext;

    ObjectMapperBuilderConfiguration(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Bean
    public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(
            List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
        Jackson2ObjectMapperBuilder builder = new MyJackson2ObjectMapperBuilder();
        builder.applicationContext(this.applicationContext);
        for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
            customizer.customize(builder);
        }
        return builder;
    }


    private static final class MyJackson2ObjectMapperBuilder
            extends Jackson2ObjectMapperBuilder {
        @Override
        public void configure(ObjectMapper objectMapper) {
            super.configure(objectMapper);
            // 1. NULL值转化为空字符串，并展现
            // 默认配置NULL不处理，如果需要将NULL转化为空字符串需要
            // 注释掉 application.properties中的spring.jackson.default-property-inclusion=non_null

//            objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
                @Override
                public void serialize(Object value, JsonGenerator jg, SerializerProvider sp) throws IOException {
                    jg.writeString("");
                }
            });

            //2.为了满足前端JS对long数据类型的支持，转化为字符串。
            // 项目中用雪花算法生成分布式ID，这些ID是Long型的。
            //当这些ID在前端通过JavaScript处理时，会存在精度丢失问题。
            SimpleModule simpleModule = new SimpleModule();
            simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
            simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
            objectMapper.registerModule(simpleModule);

        }
    }


}
